package hyl.base.flow.express;

import java.util.Iterator;

import hyl.base.flow.Track;
/**
 * 负责解析字符串
 * */
public class Depend {

	private DependNode _top;// 顶层节点
	private DependNode _cur;// 当前节点
	Depend _subExp;// 当前子表达式 /如果有多个() 指向 正在解析的那个

	private Depend(DependNode root) {
		if (root == null)
			_top = DependNode.getInstance();
		else
			_top = root;
		_cur = DependNode.getInsFromParent(_top);

	}

	public DependNode getRootNode() {
		return _top;
	}

	// 读完解析, 放入指定结构 ,用树来表达 ,上下关系为且 ,左右关系为或
	public static Depend getInstance(String str) {
		// 字符串
		// long a = System.currentTimeMillis();
		Depend root = new Depend(null);
		// 解析字符串
		// System.out.println(System.currentTimeMillis()-a);
		int len = str.length();
		for (int i = 0; i < len; i++) {
			char c = str.charAt(i); // 获取每个字符
			root.writechar(c);
		}
		// System.out.println(System.currentTimeMillis()-a);
		//root.test1(root._top, 0, "");
		root.lay3(root._top);
		return root;
	}

	// 测试查看解析的结构是否正确
	public void test1(DependNode nd, int i, String tab) {
		if (nd == null)
			return;
		if (nd.getContent() == null)
			System.out.println(tab + i + "-" + nd + " " + nd.getParent());
		else
			System.out.println(tab + i + ' ' + nd.getContent() + " " + nd + " " + nd.getParent());

		if (nd._include != null) {
			System.out.println(tab + i + "inculde:(");
			test1(nd._include, 0, tab + "   ");
			System.out.println(tab + i + "   )");
		}
		Iterator<DependNode> nds = nd.iterator();
		++i;
		while (nds.hasNext()) {
			DependNode a = nds.next();
			test1(a, i, tab + "  ");
		}
	}

	// 读一个字符
	private int writechar(Character c) {
		// 如果子表达式为空
		if (_subExp == null) {
			if (c == '(') {
				// _cur = CExpNode.getInsFromParent(_top);
				// 实例化节点作为当前节点的包含节点
				DependNode clud = DependNode.getInsExpFromParent(_cur);
				// 新建一个表达式实例,传入字符流
				_subExp = new Depend(clud);
				return 0;
			} else {
				// 按第二优先级,解析只有&|的表达式
				return lay2(c);
			}
		} else {// 传递给下一级的express 解析
			int i = _subExp.writechar(c);
			if (i == 1) {
				_subExp = null;
			}
			return 2;
		}
	}

	private int lay2(Character c) {
		switch (c) {
		case ')':
			return 1;
		case '|':
			_cur = DependNode.getInsFromParent(_top);//关键点 必须用_top
			return 2;
		case '&':			
			_cur = DependNode.getInsFromParent(_cur);
			return 2;
		}
		_cur.addChar(c);
		return 2;
	}

	/**
	 * 遍历每个节点进行解析第三层 每个节点的文本
	 */
	private void lay3(DependNode nd) {
		if (nd == null)
			return;
		if (nd._include != null) {
			lay3(nd._include);
		}
		Iterator<DependNode> nds = nd.iterator();
		while (nds.hasNext()) {
			DependNode a = nds.next();
			lay3(a);
		}
		nd.analyzing();
	}

	
	
	/**
	 * 根据拍照的状态列表中的键值对,求逻辑运算结果
	 */
	public boolean judge(Track vars) {
		if (_top == null) {
			return false;
		} else
			return calculate(_top, vars);
	}

	/**
	 * 求逻辑运算结果的递归算法
	 */
	private boolean calculate(DependNode nd, Track track) {
		if (nd == null)
			return true;
		// System.out.println(nd);
		Iterator<DependNode> nds = nd.iterator();
		boolean flag = true;// 最终结果变量
		// 计算子节点本身的逻辑运算结果
		if (nd.getContent() != null) {
			//变量
			Character ch = track.getMark(nd.getField());	
			if (ch != null) {
				//nd中的状态值 是常量
				boolean f = nd.judge(ch);
			//	 System.out.println("me " +nd.getContent()+' ' +ch + ' ' + f);
				if (!f)
					return false; // 与运算 false短路
				
			}
		}
		if (nd._include != null) {
			boolean f2 = calculate(nd._include, track);
		//	 System.out.println("in " +nd.getContent()  + ' ' + f2);
			if (!f2)
				return false;
		}
		// 计算当前元素 每个子节点的逻辑运算结果, 再统一,或运算
		if (nds.hasNext()) {
			boolean orflag = false; // 子节点逻辑运算结果变量
			while (nds.hasNext()) {
				DependNode a = nds.next();
				boolean f = calculate(a, track);
		//		 System.out.println("or " +nd.getContent()  + ' ' + f);
				if (f) {// 或运算 true 短路
					orflag = f;
					break;
				}
				// System.out.println("2 " + a.getExpress() + ' ' + f+ ' ' + orflag);
			}
			return orflag;
			// System.out.println("2 " + flag);
		}
		return flag;
	}
	// 解析 = >= <= , <> != > < @
	// 支持a > char ; a = char ; a < char
	// ;a <> char ; a != char ; a >= char ; a <= char
	// 以及 b @ char,char,char 等于 b in [char,char,char]

}
